package com.yeyks.commonReference.append.sms.impl;

import com.google.common.collect.Lists;
import com.yeyks.common.ajax.AjaxResponseBody;
import com.yeyks.common.utils.DateUtils;
import com.yeyks.common.utils.JsonUtils;
import com.yeyks.other.dto.SmsCodeDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author fuchangshuai
 * @date 2019/5/5 0005
 */
@Service
@Slf4j
public class SmsManage {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final List<String> whiteLists = Lists.newArrayList("15188445491");

    private static final String phoneKey = "user:phone:sms:code:text:";
    private static final String phoneGetCount = "user:phone:sms:code:getcount:";

    /**
     * 记录验证码
     *
     * @param phone    redis中的key
     * @param code     验证码
     * @param liveTime 激活时间 单位秒
     * @return
     */
    public AjaxResponseBody recodeCode(String phone, String code, Integer liveTime) {
        SmsCodeDTO codeDTO = new SmsCodeDTO(phone, code, new Date());
        add(phone, codeDTO, liveTime);
        return AjaxResponseBody.success(true);
    }

    /**
     * 判断是否发送限制
     *
     * @param phone redis中的key
     * @param limit 限制最短时间 单位秒
     * @return
     */
    public Boolean checkSmsLimit(String phone, Integer limit) {
        SmsCodeDTO codeDTO = get(phone);
        if (codeDTO == null) {
            return false;
        }
        LocalDateTime limitTime = DateUtils.toLocalDateTime(codeDTO.getAt()).plusSeconds(limit);
        return limitTime.compareTo(LocalDateTime.now()) > 0;
    }

    /**
     * 校验验证码
     *
     * @param phone redis中的key
     * @param code  验证码
     * @return
     */
    public Boolean checkCode(String phone, String code) {
        if (whiteLists.contains(phone)) {
            return true;
        }
        SmsCodeDTO codeDTO = get(phone);
        Boolean flag = (codeDTO != null) && codeDTO.getCode().equals(code) && phone.equals(codeDTO.getMobile());
//        if (flag) {
//            redisTemplate.delete(phone);
//        }
        return flag;
    }

    private SmsCodeDTO get(String key) {
        try {
            String value = redisTemplate.opsForValue().get(phoneKey + key);
            if (value == null || value.equals("")) {
                return null;
            }
            Long increment = redisTemplate.opsForValue().increment(phoneGetCount + key, 1);
            redisTemplate.expire(phoneGetCount + key, 60 * 1, TimeUnit.SECONDS);
            if (increment > 10) {
                redisTemplate.delete(phoneKey + key);
                redisTemplate.delete(phoneGetCount + key);
                return null;
            }
            return JsonUtils.jsonToPojo(value, SmsCodeDTO.class);
        } catch (Exception e) {
            log.warn("从redis中获取key失败{}", key);
            e.printStackTrace();
            return null;
        }
    }

    private void add(String key, SmsCodeDTO codeDTO, Integer liveTime) {
        String value = JsonUtils.objectToJson(codeDTO);
        redisTemplate.opsForValue().set(phoneKey + key, value, liveTime, TimeUnit.SECONDS);
    }
}
